package oneplay.YonghongBITools.HttpClientUtils;

import oneplay.YonghongBITools.utils.PropertiesUtil;
import oneplay.YonghongBITools.utils.SM4Util;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

public class HttpClientFactory {
    private static final Logger logger = LoggerFactory.getLogger(HttpClientFactory.class);

    public static CloseableHttpClient newInstance() {
        return newInstance(false);
    }

    public static CloseableHttpClient newInstance(boolean ssl) {
        if (ssl) {
            File keyStoreFile = new File(SM4Util.unwrap(SM4Util.decrypt(PropertiesUtil.getProperty("sslKeyStoreFile"))));
            String keyStorePassword = SM4Util.decrypt(PropertiesUtil.getProperty("sslKeyStorePassword"));
            return newInstance(keyStoreFile, keyStorePassword.toCharArray());
        }
        return HttpClients.createDefault();
    }

    /**
     * @param keyStoreFile     证书文件
     * @param keyStorePassword 证书密码
     * @return CloseableHttpClient https访问
     */
    public static CloseableHttpClient newInstance(final File keyStoreFile, final char[] keyStorePassword) {
        try {
            SSLContext sslContext = SSLContexts.custom()
                    .loadTrustMaterial(keyStoreFile, keyStorePassword)
                    .build();
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
            HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
                    .setSSLSocketFactory(socketFactory)
                    .build();
            return HttpClients.custom().setConnectionManager(connectionManager).build();
        } catch (NoSuchAlgorithmException | KeyManagementException | CertificateException | KeyStoreException |
                 IOException e) {
            logger.error(e.getMessage() + ", fall back to Default HttpClient.", e);
            return HttpClients.createDefault();
        }
    }

}
